importPackage(Packages.de.elo.ix.jscript);
importPackage(Packages.de.elo.ix.scripting);
//@include lib_Class.js
//@include lib_sol.common.Config.js
//@include lib_sol.common.ObjectUtils.js
//@include lib_sol.common.TranslateTerms.js
//@include lib_sol.common.Template.js
//@include lib_sol.common.ix.DynKwlDatabaseIterator.js
//@include lib_sol.common.ix.DynKwlSearchIterator.js
//@include lib_sol.common.ix.DynKwlFindChildrenIterator.js
//@include lib_sol.common.ix.DynKwlBLPIterator.js
var kwlConfigString, // has priority over config file, has to be valid JSON
configPath, // used together with 'kwlName' to determine the kwl config from a file
kwlName, // used together with 'configPath' to determine the kwl config from a file
__ctx = (function () {
return this;
}());
/**
* This implements generic keywordlist functionality.
*
* # Supported keywordlist types
*
* |Type|Used Iterator|
* |:-----|:------|
* |DB|Database iterator|
* |SEARCH|Search iterator|
* |CHILDREN|Children iterator|
*
* # Configuration
* It is highly recommended to use the provided app to create/edit the configurations.
*
* Each configuration (regardless of the used iterator) has to contain the following properties:
*
* |Property|Property type|Description|Note|
* |:-----|:-----|:------|:------|
* |type|String|The type used. See `Supported keywordlist types`.||
* |translate|Boolean|Determines, if translation should be applied on the `header`, the `output` and `searchParams.message`|Has to be `true`, if any of those contain translation keys.|
* |title|String|The title of the returned table. Could be a fixed string or a translation key.||
* |header|String[]|An array with the table headers. Could be a fixed strings or a translation keys.|Currently not supported in children iterator.|
* |output|String[]|An array containing the output fields.|No prefix for index fields. `IX_MAP_` prefix for map fields. `IX_MAP_` prefix and `{i}` suffix for map fields inside a form table.|
* |searchParams|Object[]|An array containing configuration for the search.|This uses the old syntax of the iterators. For better understanding the app should be used to create the configuration. Currently not supported in children iterator.|
*
* There are additional configuration properties for each iterator type.
*
* ## DB
* |Property|Property type|Description|Note|
* |:-----|:-----|:------|:------|
* |sqlQuery|String|The SQL query for the database.|Number of selected columns has to be the same as the number of `headers` and `output`. If the query contains `?` they will be replaced by evaluating the `searchParams`.|
* |jdbc|String|The name of a ressource defined in the Tomcat `META-INF/context.xml`.|Optional. If not set, the query will be executed against the ELO database.|
* |dbName|String|To use a devian schema.|Optional|
*
* ## SEARCH
* |Property|Property type|Description|Note|
* |:-----|:-----|:------|:------|
* |dataFields|String[]|The fields from the found Sord objects which will be mapped to the output fields.|Has to be of the same size as the `output` array. Only index fields are supported.|
*
* ## CHILDREN
* |Property|Property type|Description|Note|
* |:-----|:-----|:------|:------|
* |parantId|String|The start point for the children search.|Could be an arcpath, an objId or a guid.|
*
* # How to
* To implement a keywordlist using this generic class two things are necessary: a script and a configuration.
* The script needs to be implemented, because the only way to configure a field with a dynamic keyword list, is the name of a script file.
* The configuration will tell the generic class how to performe the queries and how the data should be returned.
*
* The script file has to contain the include for the `lib_Class` as well as the include for the `lib_sol.common.ix.GenericDynKwl`.
*
* The easiest way to include the configuration is directly as a JSON string in the script as a global variable `kwlConfigString`:
*
* var kwlConfigString = '{ ... }'
*
* A more convinient way to include the configuration is in a separate configuration file:
*
* var configPath = "/contract/Configuration/kwl.config",
* kwlName = "Companies";
*
* The `kwl.config` has to be JSON containing the property `Companies` which holds the configuration for this keyword list.
* For even more convinience there is an app to edit those configuration file.
*
* @author PZ, ELO Digital Office GmbH
* @version 1.04.000
*
* @eloix
* @requires sol.common.ix.DynKwlDatabaseIterator
* @requires sol.common.ix.DynKwlSearchIterator
* @requires sol.common.ix.DynKwlFindChildrenIterator
*/
sol.define("sol.common.ix.GenericDynKwl", {
initialize: function (config) {
var me = this,
cfg, providerCfg, prepare;
cfg = me.loadConfig(config);
if (!cfg) {
throw "No configuration found. Configuration has to be provided by kwlConfigString, configPath/kwlName or contructor parameter.";
}
providerCfg = me.prepareConfig(cfg);
prepare = me.prepareFunctions[cfg.type];
if (!sol.common.ObjectUtils.isFunction(prepare)) {
throw "IllegalConfigurationException: type '" + cfg.type + "' is not supported";
}
me._provider = prepare.call(me, providerCfg, cfg);
if (cfg.columnProperties) {
if (cfg.columnProperties.length !== cfg.output.length) {
throw "IllegalConfigurationException: number of columnProperties has to match the number of columns.";
}
me._provider.getColumnProperties = function () {
return cfg.columnProperties;
};
}
},
/**
* Retrieves the kwl provider which was created during initialization.
* @return {Object}
*/
getProvider: function () {
var me = this;
return me._provider;
},
/**
* @private
* Initializes the configuration. Either from `kwlConfigString`, a config file or the contructor parameter.
* @param {Object} initConfigParam
* @return {Object}
*/
loadConfig: function (initConfigParam) {
var config;
if (kwlConfigString) {
config = JSON.parse(kwlConfigString);
} else if (configPath && kwlName) {
config = sol.create("sol.common.Config", { compose: configPath }).config;
if (!config.hasOwnProperty(kwlName)) {
throw "No configuration found for '" + kwlName + "' (path='" + configPath + "')";
}
config = config[kwlName];
} else {
config = initConfigParam;
}
return config;
},
/**
* @private
* Initializes the provider config for all provider types.
* @param {Object} config
* @return {Object}
*/
prepareConfig: function (config) {
var me = this,
providerConfig;
me.translate(config);
providerConfig = {
tableTitle: config.title,
tableHeaders: config.header,
tableKeyNames: __ctx.output || config.output, // override default from configuration
formatting: config.formatting
};
if (typeof __ctx.output === "function") { // if output is overriden by a function instead of a property, this to properties are used by the mixin to determine the correct output fields
providerConfig.tableKeyNames_default = config.output;
providerConfig.tableKeyNames_configOverride = config.output_;
}
return providerConfig;
},
/**
* @private
* Performs the translation if `translate` is set to `true`.
* @param {Object} config
*/
translate: function (config) {
var required;
if (config.translate === true) {
required = [config.title];
if (config.header) { // filter null/undefined values
config.header.forEach(function (headerEntry) {
headerEntry && required.push(headerEntry);
});
}
if (config.searchParams) { // only add key, if there is a search param with a 'message' property
config.searchParams.forEach(function (param) {
param && param.message && required.push(param.message);
});
}
sol.common.TranslateTerms.require(required);
config.title = sol.common.TranslateTerms.translate(config.title);
if (config.header) {
config.header.forEach(function (column, idx) {
if (column) {
config.header[idx] = sol.common.TranslateTerms.translate(column);
}
});
}
if (config.searchParams) {
config.searchParams.forEach(function (param) {
if (param && param.message) {
param.message = sol.common.TranslateTerms.translate(param.message);
}
});
}
}
},
/**
* @private
* @property {Object}
* Lookup object for the prepare functions for all supported iterators.
* These function prepare the iterator specific configuration and create the provider.
*/
prepareFunctions: {
DB: function (providerConfig, config) {
providerConfig.sqlQuery = config.sqlQuery;
providerConfig.sqlParams = config.searchParams;
providerConfig.dbName = config.dbName;
providerConfig.jdbc = config.jdbc;
return sol.create("sol.common.ix.DynKwlDatabaseIterator", providerConfig);
},
CHILDREN: function (providerConfig, config) {
providerConfig.searchParams = config.searchParams;
providerConfig.parentId = config.parentId;
return sol.create("sol.common.ix.DynKwlFindChildrenIterator", providerConfig);
},
SEARCH: function (providerConfig, config) {
var me = this,
provider;
providerConfig.searchParams = config.searchParams;
provider = sol.create("sol.common.ix.DynKwlSearchIterator", providerConfig);
provider.dataFields = config.dataFields;
provider.getFindInfo = me.getFindInfo;
provider.getRowData = me.getRowData;
return provider;
},
BLP: function (providerConfig, config) {
var me = this,
provider;
providerConfig.queryConditions = config.searchParams;
providerConfig.queryName = config.blpQueryName;
providerConfig.queryModule = config.blpQueryModule;
providerConfig.addInId = config.blpAddInId;
providerConfig.projectId = config.blpProjectId;
providerConfig.moduleId = config.blpModuleId;
providerConfig.appToken = config.blpAppToken;
providerConfig.serverUrl = config.blpServerUrl;
provider = sol.create("sol.common.ix.DynKwlBLPIterator", providerConfig);
return provider;
}
},
/**
* @private
* Implements a find by type search that is filtered by ObjKeys.
* Used for the 'DynKwlSearchIterator'.
* @param {String[]} filterList
* @return {de.elo.ix.client.FindInfo}
*/
getFindInfo: function (filterList) {
var me = this,
findInfo, findByIndex, okeys, okey, i, param, filter;
this.log.enter("getFindInfo");
findInfo = new FindInfo();
findByIndex = new FindByIndex();
okeys = [];
if (filterList && filterList.length > 0) {
for (i = 0; i < filterList.length; i++) {
param = me.searchParams[i];
filter = filterList[i];
if (param.name && filter && (filter != "")) {
okey = new ObjKey();
okey.name = param.searchName || param.name;
okey.data = [filter];
okeys.push(okey);
}
}
}
findByIndex.objKeys = okeys;
findInfo.findByIndex = findByIndex;
findInfo.findOptions = new FindOptions();
findInfo.findOptions.searchMode = SearchModeC.ONE_TERM;
this.log.exit("getFindInfo");
return findInfo;
},
/**
* @private
* Basic implementation for search results.
* This returns the content of the sord index fields.
* Used for the 'DynKwlSearchIterator'.
* @param {de.elo.ix.client.Sord} sord
* @return {String[]}
*/
getRowData: function (sord) {
var me = this,
data = [], dataField, value,
i;
for (i = 0; i < me.dataFields.length; i++) {
dataField = me.dataFields[i];
if (sol.common.ObjectUtils.type(dataField, "string")) {
// backwards compatibility (common <= 1.13.002)
value = sol.common.SordUtils.getObjKeyValue(sord, me.dataFields[i]);
} else if (dataField.type === "SORD") {
value = String(sord[dataField.key]);
} else {
value = sol.common.SordUtils.getObjKeyValue(sord, dataField.key);
}
data.push(value);
}
return data;
}
});
function getDataIterator() {
var log = sol.create("sol.Logger", { scope: "sol.common.ix.GenericDynKwl#" + kwlName }),
provider;
try {
log.info("DynamicKeywordList (");
provider = sol.create("sol.common.ix.GenericDynKwl").getProvider();
return new DynamicKeywordDataProvider(provider);
} finally {
log.info(")getDataIterator");
}
}